Date: Tue May 28 14:39:12 2019
Scientist: Ran Yin
Sequencing (Waksman): Dibyendu Kumar
Statistics: Davit Sargsyan
Principal Investigator: Ah-Ng Kong

Meta data

# sink(file = "tmp/log_nrf2ubiome_data_visualization_may2019_v1.Rmd.txt")
# date()
options(scipen=999)
require(knitr)
Loading required package: knitr
require(kableExtra)
Loading required package: kableExtra
# # Increase mmemory size to 64 Gb----
# invisible(utils::memory.limit(65536))
options(stringsAsFactors = FALSE)
# str(knitr::opts_chunk$get())
# # NOTE: the below does not work!
# knitr::opts_chunk$set(echo = FALSE, 
#                       message = FALSE,
#                       warning = FALSE,
#                       error = FALSE)
# On Windows set multithread=FALSE----
mt <- TRUE
require(data.table)
Loading required package: data.table
data.table 1.12.2 using 18 threads (see ?getDTthreads).  Latest news: r-datatable.com
require(phyloseq)
Loading required package: phyloseq
require(ggplot2)
Loading required package: ggplot2
require(plotly)
Loading required package: plotly

Attaching package: ‘plotly’

The following object is masked from ‘package:ggplot2’:

    last_plot

The following object is masked from ‘package:stats’:

    filter

The following object is masked from ‘package:graphics’:

    layout
# require(data.table)
require(DT)
Loading required package: DT
require(shiny)
Loading required package: shiny

Attaching package: ‘shiny’

The following objects are masked from ‘package:DT’:

    dataTableOutput, renderDataTable
source("source/functions_may2019.R")
# Load data----
# Counts
load("data_may2019/ps_may2019.RData")
# Taxonomy
load("data_may2019/taxa.RData")
taxa <- data.table(seq16s = rownames(taxa),
                   taxa)
# Samples
samples <- ps_may2019@sam_data
DT::datatable(samples,
              options = list(pageLength = nrow(samples)))

Taxonomic Ranks:

King Phillip Can nOt Find Green Socks * Kingdom
* Phylum
* Class
* Order
* Family
* Genus
* Species

Prune data

Check mapping.


 Bacteria Eukaryota      <NA> 
     7994       116        19 

     Acidobacteria     Actinobacteria      Bacteroidetes      Cyanobacteria 
                 3                177               2102                 31 
   Deferribacteres Epsilonbacteraeota         Firmicutes       Fusobacteria 
                10                 27               4997                  1 
       Parabasalia    Patescibacteria     Planctomycetes     Proteobacteria 
                 1                 63                  1                202 
       Tenericutes    Verrucomicrobia               <NA> 
                84                 66                364 

First, all OTUs that were not bacteria were removed. Also, OTUs that were not mapped to a phylum were removed as these are usually sequencing artifacts.


Bacteria 
    7764 

     Acidobacteria     Actinobacteria      Bacteroidetes      Cyanobacteria 
                 3                177               2102                 31 
   Deferribacteres Epsilonbacteraeota         Firmicutes       Fusobacteria 
                10                 27               4997                  1 
   Patescibacteria     Planctomycetes     Proteobacteria        Tenericutes 
                63                  1                202                 84 
   Verrucomicrobia 
                66 

Richness (Alpha diversity)

OTU table

Total counts per sample (i.e. sequencing depth)

Counts at Phylum level

Relative abundance (%) at Phylum level

Remove phyla with relative abundance of >= 1% in less than 10% of samples (i.e. prevalence >= 10%).

Hence, only 6 out of 13 Phyla were studied in this analysis: Actinobacteria, Bacteroidetes, Firmicutes, Proteobacteria, Tenericutes and Verrucomicrobia. Relative abundance at the next taxonomic level (Class) was, therefore, computed relative to the sum of these 6 Phyla.

[1] "Actinobacteria"  "Bacteroidetes"   "Firmicutes"      "Proteobacteria" 
[5] "Tenericutes"     "Verrucomicrobia"

7,628 OTUs, down from 7,764 OTUs in the previous table.

Relative Abundance in Samples at Different Taxonomic Ranks

1. Class

p0 <- ggplot(mu,
             aes(x = Week,
                 y = x,
                 group = Treatment)) +
  facet_wrap(~ Class,
             scale = "free_y") +
  geom_line() +
  geom_point(aes(shape = Treatment,
                 color = Treatment),
             size = 5,
             alpha = 0.5)
print(p0)

p1 <- ggplot(mu,
             aes(x = x,
                 y = Class,
                 fill = Treatment,
                 shape = Week)) +
  # facet_wrap(~ Sex, nrow = 1) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_continuous("Relative Abundance (%)")
ggplotly(p1)

p2 <- ggplot(mu,
             aes(x = x,
                 y = Class,
                 fill = Treatment,
                 shape = Week)) +
  # facet_wrap(~ Sex, nrow = 1) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_log10(" Log10 Scale of Relative Abundance (%)")
ggplotly(p2)
Transformation introduced infinite values in continuous x-axis

2. Order

p0 <- ggplot(mu,
             aes(x = Week,
                 y = x,
                 group = Treatment)) +
  facet_wrap(~ Order,
             scale = "free_y") +
  geom_line() +
  geom_point(aes(shape = Treatment,
                 color = Treatment),
             size = 5,
             alpha = 0.5)
print(p0)

p1 <- ggplot(mu,
             aes(x = x,
                 y = Order,
                 fill = Treatment,
                 shape = Week)) +
  # facet_wrap(~ Sex, nrow = 1) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_continuous("Relative Abundance (%)")
ggplotly(p1)

p2 <- ggplot(mu,
             aes(x = x,
                 y = Order,
                 fill = Treatment,
                 shape = Week)) +
  # facet_wrap(~ Sex, nrow = 1) +
  geom_point(size = 3,
             alpha = 0.5) +
  geom_vline(xintercept = 1,
             linetype = "dashed") +
  scale_x_log10(" Log10 Scale of Relative Abundance (%)")
ggplotly(p2)
Transformation introduced infinite values in continuous x-axis

Session Information

sessionInfo()
R version 3.5.0 (2018-04-23)
Platform: x86_64-redhat-linux-gnu (64-bit)
Running under: Red Hat Enterprise Linux Server 7.5 (Maipo)

Matrix products: default
BLAS/LAPACK: /usr/lib64/R/lib/libRblas.so

locale:
 [1] LC_CTYPE=en_US.UTF-8       LC_NUMERIC=C               LC_TIME=en_US.UTF-8       
 [4] LC_COLLATE=en_US.UTF-8     LC_MONETARY=en_US.UTF-8    LC_MESSAGES=en_US.UTF-8   
 [7] LC_PAPER=en_US.UTF-8       LC_NAME=C                  LC_ADDRESS=C              
[10] LC_TELEPHONE=C             LC_MEASUREMENT=en_US.UTF-8 LC_IDENTIFICATION=C       

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] shiny_1.3.2       DT_0.6            plotly_4.9.0      ggplot2_3.1.1    
[5] phyloseq_1.26.1   data.table_1.12.2 kableExtra_1.1.0  knitr_1.23       

loaded via a namespace (and not attached):
 [1] Biobase_2.42.0      httr_1.4.0          tidyr_0.8.3         jsonlite_1.6       
 [5] viridisLite_0.3.0   splines_3.5.0       foreach_1.4.4       assertthat_0.2.1   
 [9] stats4_3.5.0        yaml_2.2.0          pillar_1.4.0        lattice_0.20-35    
[13] glue_1.3.1          digest_0.6.19       promises_1.0.1      XVector_0.22.0     
[17] rvest_0.3.4         colorspace_1.4-1    httpuv_1.5.1        htmltools_0.3.6    
[21] Matrix_1.2-14       plyr_1.8.4          pkgconfig_2.0.2     zlibbioc_1.28.0    
[25] xtable_1.8-4        purrr_0.3.2         scales_1.0.0        webshot_0.5.1      
[29] later_0.8.0         tibble_2.1.1        mgcv_1.8-23         IRanges_2.16.0     
[33] withr_2.1.2         BiocGenerics_0.28.0 lazyeval_0.2.2      mime_0.6           
[37] survival_2.41-3     magrittr_1.5        crayon_1.3.4        evaluate_0.13      
[41] nlme_3.1-137        MASS_7.3-49         xml2_1.2.0          vegan_2.5-5        
[45] tools_3.5.0         hms_0.4.2           stringr_1.4.0       Rhdf5lib_1.4.3     
[49] S4Vectors_0.20.1    munsell_0.5.0       cluster_2.0.7-1     Biostrings_2.50.2  
[53] ade4_1.7-13         compiler_3.5.0      rlang_0.3.4         rhdf5_2.26.2       
[57] grid_3.5.0          iterators_1.0.10    biomformat_1.10.1   rstudioapi_0.10    
[61] htmlwidgets_1.3     crosstalk_1.0.0     igraph_1.2.4.1      labeling_0.3       
[65] rmarkdown_1.12      gtable_0.3.0        codetools_0.2-15    multtest_2.38.0    
[69] reshape2_1.4.3      R6_2.4.0            dplyr_0.8.1         permute_0.9-5      
[73] readr_1.3.1         ape_5.3             stringi_1.4.3       parallel_3.5.0     
[77] Rcpp_1.0.1          tidyselect_0.2.5    xfun_0.7           
LS0tCnRpdGxlOiAiTnJmMiBCTDYgUEVJVEMgMTZTIE1pY3JvYmlvbWUgRGF0YSBWaXN1YWxpemF0aW9uIgpvdXRwdXQ6IAogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHllcwogICAgdG9jX2Zsb2F0OiB5ZXMKLS0tCkRhdGU6IGByIGRhdGUoKWAgICAgIApTY2llbnRpc3Q6IFtSYW4gWWluXShtYWlsdG86cnkxNDdAc2NhcmxldG1haWwucnV0Z2Vycy5lZHUpICAgICAgClNlcXVlbmNpbmcgKFdha3NtYW4pOiBbRGlieWVuZHUgS3VtYXJdKG1haWx0bzpka0B3YWtzbWFuLnJ1dGdlcnMuZWR1KSAgICAgIApTdGF0aXN0aWNzOiBbRGF2aXQgU2FyZ3N5YW5dKG1haWx0bzpzYXJnZGF2aWRAZ21haWwuY29tKSAgICAgIApQcmluY2lwYWwgSW52ZXN0aWdhdG9yOiBbQWgtTmcgS29uZ10obWFpbHRvOmtvbmd0QHBoYXJtYWN5LnJ1dGdlcnMuZWR1KSAKCiMgTWV0YSBkYXRhCmBgYHtyIGhlYWRlcn0KIyBzaW5rKGZpbGUgPSAidG1wL2xvZ19ucmYydWJpb21lX2RhdGFfdmlzdWFsaXphdGlvbl9tYXkyMDE5X3YxLlJtZC50eHQiKQojIGRhdGUoKQpvcHRpb25zKHNjaXBlbj05OTkpCgpyZXF1aXJlKGtuaXRyKQpyZXF1aXJlKGthYmxlRXh0cmEpCgojICMgSW5jcmVhc2UgbW1lbW9yeSBzaXplIHRvIDY0IEdiLS0tLQojIGludmlzaWJsZSh1dGlsczo6bWVtb3J5LmxpbWl0KDY1NTM2KSkKb3B0aW9ucyhzdHJpbmdzQXNGYWN0b3JzID0gRkFMU0UpCiMgc3RyKGtuaXRyOjpvcHRzX2NodW5rJGdldCgpKQojICMgTk9URTogdGhlIGJlbG93IGRvZXMgbm90IHdvcmshCiMga25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBGQUxTRSwgCiMgICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2UgPSBGQUxTRSwKIyAgICAgICAgICAgICAgICAgICAgICAgd2FybmluZyA9IEZBTFNFLAojICAgICAgICAgICAgICAgICAgICAgICBlcnJvciA9IEZBTFNFKQoKIyBPbiBXaW5kb3dzIHNldCBtdWx0aXRocmVhZD1GQUxTRS0tLS0KbXQgPC0gVFJVRQoKcmVxdWlyZShkYXRhLnRhYmxlKQpyZXF1aXJlKHBoeWxvc2VxKQpyZXF1aXJlKGdncGxvdDIpCnJlcXVpcmUocGxvdGx5KQojIHJlcXVpcmUoZGF0YS50YWJsZSkKcmVxdWlyZShEVCkKcmVxdWlyZShzaGlueSkKc291cmNlKCJzb3VyY2UvZnVuY3Rpb25zX21heTIwMTkuUiIpCgojIExvYWQgZGF0YS0tLS0KIyBDb3VudHMKbG9hZCgiZGF0YV9tYXkyMDE5L3BzX21heTIwMTkuUkRhdGEiKQoKIyBUYXhvbm9teQpsb2FkKCJkYXRhX21heTIwMTkvdGF4YS5SRGF0YSIpCnRheGEgPC0gZGF0YS50YWJsZShzZXExNnMgPSByb3duYW1lcyh0YXhhKSwKICAgICAgICAgICAgICAgICAgIHRheGEpCgojIFNhbXBsZXMKc2FtcGxlcyA8LSBwc19tYXkyMDE5QHNhbV9kYXRhCkRUOjpkYXRhdGFibGUoc2FtcGxlcywKICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gbnJvdyhzYW1wbGVzKSkpCmBgYAoKIyBUYXhvbm9taWMgUmFua3M6CioqSyoqaW5nICoqUCoqaGlsbGlwICoqQyoqYW4gbioqTyoqdCAqKkYqKmluZCAqKkcqKnJlZW4gKipTKipvY2tzCiogS2luZ2RvbSAgICAgICAgICAgICAgICAKKiBQaHlsdW0gICAgICAgICAgICAgICAgICAgIAoqIENsYXNzICAgICAgICAgICAgICAgICAgIAoqIE9yZGVyICAgICAgICAgICAgICAgICAgIAoqIEZhbWlseSAgICAgCiogR2VudXMgICAgIAoqIFNwZWNpZXMgIAoKIyBQcnVuZSBkYXRhCkNoZWNrIG1hcHBpbmcuCmBgYHtyIGNoZWNrX21hcHBpbmcsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQp0YWJsZSh0YXhfdGFibGUocHNfbWF5MjAxOSlbLCAiS2luZ2RvbSJdLCAKICAgICAgZXhjbHVkZSA9IE5VTEwpCnRhYmxlKHRheF90YWJsZShwc19tYXkyMDE5KVssICJQaHlsdW0iXSwgCiAgICAgIGV4Y2x1ZGUgPSBOVUxMKQpgYGAKCkZpcnN0LCBhbGwgT1RVcyB0aGF0IHdlcmUgbm90IGJhY3RlcmlhIHdlcmUgcmVtb3ZlZC4gQWxzbywgT1RVcyB0aGF0IHdlcmUgbm90IG1hcHBlZCB0byBhIHBoeWx1bSB3ZXJlIHJlbW92ZWQgYXMgdGhlc2UgYXJlICB1c3VhbGx5IHNlcXVlbmNpbmcgYXJ0aWZhY3RzLgpgYGB7ciBwcnVuZSwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CiMgMS4gS2VlcCBiYWN0ZXJpYSBvbmx5IChpLmUuIHJlbW92ZSBhcmNoZWEgYW5kIGV1Y2FyeW90YSkKIyAyLiBSZW1vdmUgaWYgcGh5bHVtIGlzIHVubWFwcGVkCnBzMCA8LSBzdWJzZXRfdGF4YShwc19tYXkyMDE5LCAKICAgICAgICAgICAgICAgICAgIEtpbmdkb20gPT0gIkJhY3RlcmlhIiAmCiAgICAgICAgICAgICAgICAgICAgICFpcy5uYShQaHlsdW0pKQoKdGFibGUodGF4X3RhYmxlKHBzMClbLCAiS2luZ2RvbSJdLCAKICAgICAgZXhjbHVkZSA9IE5VTEwpCnRhYmxlKHRheF90YWJsZShwczApWywgIlBoeWx1bSJdLCAKICAgICAgZXhjbHVkZSA9IE5VTEwpCmBgYAoKIyBSaWNobmVzcyAoQWxwaGEgZGl2ZXJzaXR5KQpgYGB7ciByaWNobmVzcywgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTEwLGZpZy5oZWlnaHQ9NX0KcHMwQHNhbV9kYXRhJERpZXRfV2VlayA8LSBwYXN0ZShzYW1wbGVzJFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgc2FtcGxlcyRXRUVLLAogICAgICAgICAgICAgICAgICAgICAgICAgICBzZXAgPSAiXyIpCnBzMEBzYW1fZGF0YSRJRCA8LSBzdWJzdHIoeCA9IHBzMEBzYW1fZGF0YSRTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQgPSAyLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdG9wID0gMykKcDEgPC0gcGxvdF9yaWNobmVzcyhwczAsCiAgICAgICAgICAgICAgICAgICAgeCA9ICJEaWV0X1dlZWsiLCAKICAgICAgICAgICAgICAgICAgICBtZWFzdXJlcyA9ICJTaGFubm9uIiwKICAgICAgICAgICAgICAgICAgICBjb2xvciA9ICJJRCIpICsKICBnZW9tX2xpbmUoYWVzKGdyb3VwID0gSUQpLAogICAgICAgICAgICBjb2xvciA9ICJibGFjayIpICsKICBnZW9tX3BvaW50KHNoYXBlID0gMjEsCiAgICAgICAgICAgICBzaXplID0gMywKICAgICAgICAgICAgIGNvbG9yID0gImJsYWNrIikKZ2dwbG90bHkocDEpCmBgYAoKIyBPVFUgdGFibGUKYGBge3Igb3R1X3RhYmxlLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0Kb3R1IDwtIGRhdGEudGFibGUocHMwQHRheF90YWJsZUAuRGF0YSwKICAgICAgICAgICAgICAgICAgdChwczBAb3R1X3RhYmxlQC5EYXRhKSkKRFQ6OmRhdGF0YWJsZShvdHUpCmBgYAoKIyBUb3RhbCBjb3VudHMgcGVyIHNhbXBsZSAoaS5lLiBzZXF1ZW5jaW5nIGRlcHRoKQpgYGB7ciBUYXgsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xMCxmaWcuaGVpZ2h0PTV9CnQxIDwtIGNvbFN1bXMob3R1WywgNzpuY29sKG90dSldKQp0MSA8LSBkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gbmFtZXModDEpLAogICAgICAgICAgICAgICAgIFRvdGFsID0gdDEpCgp0bXAgPC0gZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IHNhbXBsZXMkU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgIFRSRUFUTUVOVCA9IHNhbXBsZXMkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICBXRUVLID0gc2FtcGxlcyRXRUVLKQoKdDEgPC0gbWVyZ2UodG1wLAogICAgICAgICAgICB0MSwKICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQoKcDEgPC0gZ2dwbG90KHQxLAogICAgICAgICAgICAgYWVzKHggPSBTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICB5ID0gVG90YWwsCiAgICAgICAgICAgICAgICAgZmlsbCA9IFRSRUFUTUVOVCwKICAgICAgICAgICAgICAgICBjb2xvdXIgPSBXRUVLKSkgKwogIGdlb21fYmFyKHN0YXQgPSAiaWRlbnRpdHkiKSArCiAgc2NhbGVfeF9kaXNjcmV0ZSgiU2FtcGxlIE5hbWUiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKCJOdW1iZXIgb2YgUmVhZHMiKSArCiAgc2NhbGVfZmlsbF9kaXNjcmV0ZSgiR3JvdXAiKSArCiAgdGhlbWUoYXhpcy50ZXh0LnggPSBlbGVtZW50X3RleHQoYW5nbGUgPSA5MCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKSAKZ2dwbG90bHkocDEpCmBgYAoKIyBDb3VudHMgYXQgUGh5bHVtIGxldmVsCmBgYHtyIGNvdW50c19wLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0KY291bnRzX3AgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dSwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGFnZ3JfYnkgPSAiUGh5bHVtIikKRFQ6OmRhdGF0YWJsZShjb3VudHNfcCwKICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gbnJvdyhjb3VudHNfcCkpKQpgYGAKCiMgUmVsYXRpdmUgYWJ1bmRhbmNlICglKSBhdCBQaHlsdW0gbGV2ZWwKYGBge3IgcmFfcCwgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0V9CnJhX3AgPC0gcmFfYnlfdGF4X3JhbmsoY291bnRzID0gY291bnRzX3ApCkRUOjpkYXRhdGFibGUocmFfcCwKICAgICAgICAgICAgICBvcHRpb25zID0gbGlzdChwYWdlTGVuZ3RoID0gbnJvdyhyYV9wKSkpCmBgYAoKUmVtb3ZlIHBoeWxhIHdpdGggcmVsYXRpdmUgYWJ1bmRhbmNlIG9mID49IDElIGluIGxlc3MgdGhhbiAxMCUgb2Ygc2FtcGxlcyAoaS5lLiBwcmV2YWxlbmNlID49IDEwJSkuCgpgYGB7ciBwcmV2X3AsIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFfQp0MSA8LSBkYXRhLnRhYmxlKFBoeWx1bSA9IHJhX3AkUGh5bHVtLAogICAgICAgICAgICAgICAgIFByZXZhbGVuY2UgPSByb3VuZCgxMDAqcm93U3VtcyhyYV9wWywgMjpuY29sKHJhX3ApXSA+PSAxKS8zMCwgMSkpCkRUOjpkYXRhdGFibGUodDEsCiAgICAgICAgICAgICAgb3B0aW9ucyA9IGxpc3QocGFnZUxlbmd0aCA9IG5yb3cocmFfcCkpKQpgYGAKCkhlbmNlLCBvbmx5IDYgb3V0IG9mIDEzIFBoeWxhIHdlcmUgc3R1ZGllZCBpbiB0aGlzIGFuYWx5c2lzOiBBY3Rpbm9iYWN0ZXJpYSwgQmFjdGVyb2lkZXRlcywgRmlybWljdXRlcywgUHJvdGVvYmFjdGVyaWEsIFRlbmVyaWN1dGVzIGFuZCBWZXJydWNvbWljcm9iaWEuIFJlbGF0aXZlIGFidW5kYW5jZSBhdCB0aGUgbmV4dCB0YXhvbm9taWMgbGV2ZWwgKENsYXNzKSB3YXMsIHRoZXJlZm9yZSwgY29tcHV0ZWQgcmVsYXRpdmUgdG8gdGhlIHN1bSBvZiB0aGVzZSA2IFBoeWxhLgoKYGBge3Iga2VlcF82X3BoeWxhLCB3YXJuaW5nPUZBTFNFLGVjaG89RkFMU0UsbWVzc2FnZT1GQUxTRX0Ka2VlcF9wIDwtIHQxJFBoeWx1bVt0MSRQcmV2YWxlbmNlID49IDEwXQprZWVwX3AgCnBzMSA8LSBzdWJzZXRfdGF4YShwczAsIAogICAgICAgICAgICAgICAgICAgUGh5bHVtICVpbiUga2VlcF9wICkKb3R1MSA8LSBkYXRhLnRhYmxlKHBzMUB0YXhfdGFibGVALkRhdGEsCiAgICAgICAgICAgICAgICAgICB0KHBzMUBvdHVfdGFibGVALkRhdGEpKQpEVDo6ZGF0YXRhYmxlKG90dTEpCmBgYAoKNyw2MjggT1RVcywgZG93biBmcm9tIDcsNzY0IE9UVXMgaW4gdGhlIHByZXZpb3VzIHRhYmxlLgoKCiMgUmVsYXRpdmUgQWJ1bmRhbmNlIGluIFNhbXBsZXMgYXQgRGlmZmVyZW50IFRheG9ub21pYyBSYW5rcwojIyAxLiBDbGFzcwpgYGB7ciBjb3VudHNfYywgd2FybmluZz1GQUxTRSxlY2hvPUZBTFNFLG1lc3NhZ2U9RkFMU0UsZmlnLndpZHRoPTEwLGZpZy5oZWlnaHQ9Nn0KY291bnRzX2MgPC0gY291bnRzX2J5X3RheF9yYW5rKGR0MSA9IG90dTEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBhZ2dyX2J5ID0gIkNsYXNzIikKcmFfYyA8LSByYV9ieV90YXhfcmFuayhjb3VudHNfYykKCnRheC5yYW5rcyA8LSB1bmlxdWUob3R1MVssIGMoIlBoeWx1bSIsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIkNsYXNzIildKQoKcmFfYyA8LSBtZXJnZSh0YXgucmFua3MsCiAgICAgICAgICAgICAgcmFfYywKICAgICAgICAgICAgICBieSA9ICJDbGFzcyIpCgp0b3RhbCA8LSByb3dTdW1zKHJhX2NbLCAzOm5jb2wocmFfYyldKQoKcmFfYyRDbGFzcyA8LSBmYWN0b3IocmFfYyRDbGFzcywKICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gcmFfYyRDbGFzc1tvcmRlcih0b3RhbCldKQoKcmFfYyRQaHlsdW0gPC0gZmFjdG9yKHJhX2MkUGh5bHVtLAogICAgICAgICAgICAgICAgICAgICAgbGV2ZWxzID0gdW5pcXVlKHJhX2MkUGh5bHVtW29yZGVyKHRvdGFsKV0pKQp0bXAgPC0gbWVsdC5kYXRhLnRhYmxlKGRhdGEgPSByYV9jLAogICAgICAgICAgICAgICAgICAgICAgIGlkLnZhcnMgPSAxOjIsCiAgICAgICAgICAgICAgICAgICAgICAgbWVhc3VyZS52YXJzID0gMzpuY29sKGNvdW50c19jKSwKICAgICAgICAgICAgICAgICAgICAgICB2YXJpYWJsZS5uYW1lID0gIlNBTVBMRV9OQU1FIiwKICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZS5uYW1lID0gIlJBIikKCnRtcCA8LSBtZXJnZShkYXRhLnRhYmxlKFNBTVBMRV9OQU1FID0gc2FtcGxlcyRTQU1QTEVfTkFNRSwKICAgICAgICAgICAgICAgICAgICAgICAgV0VFSyA9IHNhbXBsZXMkV0VFSywKICAgICAgICAgICAgICAgICAgICAgICAgVFJFQVRNRU5UID0gc2FtcGxlcyRUUkVBVE1FTlQpLAogICAgICAgICAgICAgdG1wLAogICAgICAgICAgICAgYnkgPSAiU0FNUExFX05BTUUiKQoKIyBQbG90IHNhbXBsZXMKcDEgPC0gZ2dwbG90KHRtcCwKICAgICAgICAgICAgIGFlcyh4ID0gU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgeSA9IFJBLAogICAgICAgICAgICAgICAgIGZpbGwgPSBDbGFzcywKICAgICAgICAgICAgICAgICBjb2xvciA9IFBoeWx1bSkpICsKICBmYWNldF93cmFwKH4gV0VFSyArIFRSRUFUTUVOVCwKICAgICAgICAgICAgIHNjYWxlcyA9ICJmcmVlX3giLAogICAgICAgICAgICAgbnJvdyA9IDMpICsKICBnZW9tX2JhcihzdGF0ID0gImlkZW50aXR5IikgKwogIHNjYWxlX3hfZGlzY3JldGUoIiIpICsKICBzY2FsZV95X2NvbnRpbnVvdXMoZXhwYW5kID0gYygwLCAwKSkgKwogIHRoZW1lKGF4aXMudGV4dC54ID0gZWxlbWVudF90ZXh0KGFuZ2xlID0gMCwKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoanVzdCA9IDEpKQpnZ3Bsb3RseShwMSkKYGBgCgpgYGB7ciBtZWFuc19jLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQpscmEgPC0gcmFfbWVsdChyYSA9IHJhX2MsCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzYW1wbGVzLAogICAgICAgICAgICAgICBzYW1wbGVfbmFtZSA9ICJTQU1QTEVfTkFNRSIpCgptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gbGlzdChXZWVrID0gbHJhJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVhdG1lbnQgPSBscmEkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQ2xhc3MgPSBscmEkQ2xhc3MpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSAibWVhbiIpKQptdVssIHRvdGFsIDo9IHN1bSh4KSwKICAgYnkgPSAiQ2xhc3MiXQp1bCA8LSB1bmlxdWUobXVbLCBjKCJDbGFzcyIsIAogICAgICAgICAgICAgICAgICAgICJ0b3RhbCIpXSkKdWwgPC0gdWxbb3JkZXIodG90YWwpLF0KbXUkQ2xhc3MgPC0gZmFjdG9yKG11JENsYXNzLAogICAgICAgICAgICAgICAgICAgbGV2ZWwgPSB1bCRDbGFzcykKRFQ6OmRhdGF0YWJsZShtdSkKYGBgCgoKYGBge3IgbWVhbnNfY19wMCwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSA1fQpwMCA8LSBnZ3Bsb3QobXUsCiAgICAgICAgICAgICBhZXMoeCA9IFdlZWssCiAgICAgICAgICAgICAgICAgeSA9IHgsCiAgICAgICAgICAgICAgICAgZ3JvdXAgPSBUcmVhdG1lbnQpKSArCiAgZmFjZXRfd3JhcCh+IENsYXNzLAogICAgICAgICAgICAgc2NhbGUgPSAiZnJlZV95IikgKwogIGdlb21fbGluZSgpICsKICBnZW9tX3BvaW50KGFlcyhzaGFwZSA9IFRyZWF0bWVudCwKICAgICAgICAgICAgICAgICBjb2xvciA9IFRyZWF0bWVudCksCiAgICAgICAgICAgICBzaXplID0gNSwKICAgICAgICAgICAgIGFscGhhID0gMC41KQpwcmludChwMCkKYGBgCgoKYGBge3IgbWVhbnNfY19wMSwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSAxMH0KcDEgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSB4LAogICAgICAgICAgICAgICAgIHkgPSBDbGFzcywKICAgICAgICAgICAgICAgICBmaWxsID0gVHJlYXRtZW50LAogICAgICAgICAgICAgICAgIHNoYXBlID0gV2VlaykpICsKICAjIGZhY2V0X3dyYXAofiBTZXgsIG5yb3cgPSAxKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwKICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKQpnZ3Bsb3RseShwMSkKCnAyIDwtIGdncGxvdChtdSwKICAgICAgICAgICAgIGFlcyh4ID0geCwKICAgICAgICAgICAgICAgICB5ID0gQ2xhc3MsCiAgICAgICAgICAgICAgICAgZmlsbCA9IFRyZWF0bWVudCwKICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArCiAgIyBmYWNldF93cmFwKH4gU2V4LCBucm93ID0gMSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgc2NhbGVfeF9sb2cxMCgiIExvZzEwIFNjYWxlIG9mIFJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKQoKZ2dwbG90bHkocDIpCmBgYAoKIyMgMi4gT3JkZXIKYGBge3IgY291bnRzX28sIHdhcm5pbmc9RkFMU0UsZWNobz1GQUxTRSxtZXNzYWdlPUZBTFNFLGZpZy53aWR0aD0xMCxmaWcuaGVpZ2h0PTZ9CmNvdW50c19vIDwtIGNvdW50c19ieV90YXhfcmFuayhkdDEgPSBvdHUxLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgYWdncl9ieSA9ICJPcmRlciIpCnJhX28gPC0gcmFfYnlfdGF4X3JhbmsoY291bnRzX28pCgp0YXgucmFua3MgPC0gdW5pcXVlKG90dTFbLCBjKCJQaHlsdW0iLAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICJPcmRlciIpXSkKCnJhX28gPC0gbWVyZ2UodGF4LnJhbmtzLAogICAgICAgICAgICAgIHJhX28sCiAgICAgICAgICAgICAgYnkgPSAiT3JkZXIiKQoKdG90YWwgPC0gcm93U3VtcyhyYV9vWywgMzpuY29sKHJhX28pXSkKCnJhX28kT3JkZXIgPC0gZmFjdG9yKHJhX28kT3JkZXIsCiAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHJhX28kT3JkZXJbb3JkZXIodG90YWwpXSkKCnJhX28kUGh5bHVtIDwtIGZhY3RvcihyYV9vJFBoeWx1bSwKICAgICAgICAgICAgICAgICAgICAgIGxldmVscyA9IHVuaXF1ZShyYV9vJFBoeWx1bVtvcmRlcih0b3RhbCldKSkKdG1wIDwtIG1lbHQuZGF0YS50YWJsZShkYXRhID0gcmFfbywKICAgICAgICAgICAgICAgICAgICAgICBpZC52YXJzID0gMToyLAogICAgICAgICAgICAgICAgICAgICAgIG1lYXN1cmUudmFycyA9IDM6bmNvbChjb3VudHNfbyksCiAgICAgICAgICAgICAgICAgICAgICAgdmFyaWFibGUubmFtZSA9ICJTQU1QTEVfTkFNRSIsCiAgICAgICAgICAgICAgICAgICAgICAgdmFsdWUubmFtZSA9ICJSQSIpCgp0bXAgPC0gbWVyZ2UoZGF0YS50YWJsZShTQU1QTEVfTkFNRSA9IHNhbXBsZXMkU0FNUExFX05BTUUsCiAgICAgICAgICAgICAgICAgICAgICAgIFdFRUsgPSBzYW1wbGVzJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgIFRSRUFUTUVOVCA9IHNhbXBsZXMkVFJFQVRNRU5UKSwKICAgICAgICAgICAgIHRtcCwKICAgICAgICAgICAgIGJ5ID0gIlNBTVBMRV9OQU1FIikKCiMgUGxvdCBzYW1wbGVzCnAxIDwtIGdncGxvdCh0bXAsCiAgICAgICAgICAgICBhZXMoeCA9IFNBTVBMRV9OQU1FLAogICAgICAgICAgICAgICAgIHkgPSBSQSwKICAgICAgICAgICAgICAgICBmaWxsID0gT3JkZXIsCiAgICAgICAgICAgICAgICAgY29sb3IgPSBQaHlsdW0pKSArCiAgZmFjZXRfd3JhcCh+IFdFRUsgKyBUUkVBVE1FTlQsCiAgICAgICAgICAgICBzY2FsZXMgPSAiZnJlZV94IiwKICAgICAgICAgICAgIG5yb3cgPSAzKSArCiAgZ2VvbV9iYXIoc3RhdCA9ICJpZGVudGl0eSIpICsKICBzY2FsZV94X2Rpc2NyZXRlKCIiKSArCiAgc2NhbGVfeV9jb250aW51b3VzKGV4cGFuZCA9IGMoMCwgMCkpICsKICB0aGVtZShheGlzLnRleHQueCA9IGVsZW1lbnRfdGV4dChhbmdsZSA9IDAsCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGp1c3QgPSAxKSkKZ2dwbG90bHkocDEpCmBgYApgYGB7ciBtZWFuc19vLCBlY2hvID0gRkFMU0UsIHdhcm5pbmcgPSBGQUxTRSwgbWVzc2FnZSA9IEZBTFNFfQpscmEgPC0gcmFfbWVsdChyYSA9IHJhX28sCiAgICAgICAgICAgICAgIHNhbXBsZXMgPSBzYW1wbGVzLAogICAgICAgICAgICAgICBzYW1wbGVfbmFtZSA9ICJTQU1QTEVfTkFNRSIpCgptdSA8LSBkYXRhLnRhYmxlKGFnZ3JlZ2F0ZShscmEkUkEsCiAgICAgICAgICAgICAgICAgICAgICAgICAgIGJ5ID0gbGlzdChXZWVrID0gbHJhJFdFRUssCiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBUcmVhdG1lbnQgPSBscmEkVFJFQVRNRU5ULAogICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgT3JkZXIgPSBscmEkT3JkZXIpLAogICAgICAgICAgICAgICAgICAgICAgICAgICBGVU4gPSAibWVhbiIpKQptdVssIHRvdGFsIDo9IHN1bSh4KSwKICAgYnkgPSAiT3JkZXIiXQp1bCA8LSB1bmlxdWUobXVbLCBjKCJPcmRlciIsIAogICAgICAgICAgICAgICAgICAgICJ0b3RhbCIpXSkKdWwgPC0gdWxbb3JkZXIodG90YWwpLF0KbXUkT3JkZXIgPC0gZmFjdG9yKG11JE9yZGVyLAogICAgICAgICAgICAgICAgICAgbGV2ZWwgPSB1bCRPcmRlcikKRFQ6OmRhdGF0YWJsZShtdSkKYGBgCgpgYGB7ciBtZWFuc19vX3AwLCBmaWcud2lkdGggPSAxMCwgZmlnLmhlaWdodCA9IDV9CnAwIDwtIGdncGxvdChtdSwKICAgICAgICAgICAgIGFlcyh4ID0gV2VlaywKICAgICAgICAgICAgICAgICB5ID0geCwKICAgICAgICAgICAgICAgICBncm91cCA9IFRyZWF0bWVudCkpICsKICBmYWNldF93cmFwKH4gT3JkZXIsCiAgICAgICAgICAgICBzY2FsZSA9ICJmcmVlX3kiKSArCiAgZ2VvbV9saW5lKCkgKwogIGdlb21fcG9pbnQoYWVzKHNoYXBlID0gVHJlYXRtZW50LAogICAgICAgICAgICAgICAgIGNvbG9yID0gVHJlYXRtZW50KSwKICAgICAgICAgICAgIHNpemUgPSA1LAogICAgICAgICAgICAgYWxwaGEgPSAwLjUpCnByaW50KHAwKQpgYGAKYGBge3IgbWVhbnNfb19wMSwgZmlnLndpZHRoID0gMTAsIGZpZy5oZWlnaHQgPSAxMH0KcDEgPC0gZ2dwbG90KG11LAogICAgICAgICAgICAgYWVzKHggPSB4LAogICAgICAgICAgICAgICAgIHkgPSBPcmRlciwKICAgICAgICAgICAgICAgICBmaWxsID0gVHJlYXRtZW50LAogICAgICAgICAgICAgICAgIHNoYXBlID0gV2VlaykpICsKICAjIGZhY2V0X3dyYXAofiBTZXgsIG5yb3cgPSAxKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywKICAgICAgICAgICAgIGFscGhhID0gMC41KSArCiAgZ2VvbV92bGluZSh4aW50ZXJjZXB0ID0gMSwKICAgICAgICAgICAgIGxpbmV0eXBlID0gImRhc2hlZCIpICsKICBzY2FsZV94X2NvbnRpbnVvdXMoIlJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKQpnZ3Bsb3RseShwMSkKCnAyIDwtIGdncGxvdChtdSwKICAgICAgICAgICAgIGFlcyh4ID0geCwKICAgICAgICAgICAgICAgICB5ID0gT3JkZXIsCiAgICAgICAgICAgICAgICAgZmlsbCA9IFRyZWF0bWVudCwKICAgICAgICAgICAgICAgICBzaGFwZSA9IFdlZWspKSArCiAgIyBmYWNldF93cmFwKH4gU2V4LCBucm93ID0gMSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsCiAgICAgICAgICAgICBhbHBoYSA9IDAuNSkgKwogIGdlb21fdmxpbmUoeGludGVyY2VwdCA9IDEsCiAgICAgICAgICAgICBsaW5ldHlwZSA9ICJkYXNoZWQiKSArCiAgc2NhbGVfeF9sb2cxMCgiIExvZzEwIFNjYWxlIG9mIFJlbGF0aXZlIEFidW5kYW5jZSAoJSkiKQoKZ2dwbG90bHkocDIpCmBgYAoKIyBTZXNzaW9uIEluZm9ybWF0aW9uCmBgYHtyIGluZm8sZXZhbD1UUlVFfQpzZXNzaW9uSW5mbygpCmBgYA==